﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DcsGauges.Gui.Gauges.Interfaces;
using Microsoft.Xna.Framework.Graphics;
using DcsGauges.Shared.DataStructures;
using DcsGauges.Gui.Rendering;
using DcsGauges.DataStructures;
using Microsoft.Xna.Framework;
using DcsGauges.Input.Processors;
using DcsGauges.Input.Events;

namespace DcsGauges.Gui.Gauges
{
    class TriLeverGauge : GuiRenderableBase, ITriggerGauge
    {
        #region Inner Types

        public enum LeverState
        {
            State0,
            State1,
            State2,
        }

        #endregion


        #region Fields & Properties

        private Texture2D                                   backgroundTexture                       = null;
        private Dictionary<LeverState, Texture2D>           leverTextures                           = new Dictionary<LeverState, Texture2D>();
        private DcsProperty                                 property                                = null;
        private IGaugeValueConverter<float, LeverState>     valueConverter                          = null;
        private VerticalSwipeProcessor                      inputProcessor                          = null;

        #endregion


        #region Constructors

        public TriLeverGauge(GuiRenderableBase parent, URect area, Texture2D backgroundTexture, DcsProperty property,
            Texture2D state0LeverTex, Texture2D state1LeverTex, Texture2D state2LeverTex, 
            IGaugeValueConverter<float, LeverState> valueConverter) : base(parent, area)
        {
            this.backgroundTexture                      = backgroundTexture;
            this.valueConverter                         = valueConverter;
            this.property                               = property;
            this.Value                                  = 0.0f;

            this.leverTextures.Add(LeverState.State0, state0LeverTex);
            this.leverTextures.Add(LeverState.State1, state1LeverTex);
            this.leverTextures.Add(LeverState.State2, state2LeverTex);

            this.inputProcessor                         = new VerticalSwipeProcessor(this);
            this.inputProcessor.SwipeEvent              += new EventHandler<VerticalSwipeProcessor.SwipeEventArgs>(OnInputProcessorHandleSwipeEvent);
        }

        #endregion


        #region Interface Implementation

        #region Properties

        public DcsProperty DataProperty
        {
            get { return this.property; }
        }



        public float Value
        {
            get; set;
        }

        #endregion

        #region Events

        public event EventHandler<TriggerValueEventArgs>  TriggerEvent          = delegate { };

        #endregion

        #endregion


        #region Overrides

        public override void Render(SpriteBatch spriteBatch, GraphicsDevice device, Rectangle parentRect, float globalZIndex)
        {
            Rectangle viewportRect      = this.CalcViewportRect(this.Parent.ViewportRect, null);
            LeverState state            = this.valueConverter.Convert(this.Value);
            Texture2D stateTexture      = this.leverTextures[state];

            if(this.backgroundTexture != null)
            {
                spriteBatch.Draw(this.backgroundTexture, viewportRect, null, Color.White, 0.0f, Vector2.Zero, SpriteEffects.None, base.NextFrontIndex(globalZIndex, 1));
            }

            if (stateTexture != null)
            {
                spriteBatch.Draw(stateTexture, viewportRect, null, Color.White, 0.0f, Vector2.Zero, SpriteEffects.None, base.NextFrontIndex(globalZIndex, 2));
            }

        }

        public override void InjectMouseEvent(MouseEvent evt, GameTime gt)
        {
            this.inputProcessor.InjectMouseEvent(evt, gt);
        }

        #endregion


        #region Event Handlers
    
        void OnInputProcessorHandleSwipeEvent(object sender, VerticalSwipeProcessor.SwipeEventArgs e)
        {
            this.FireTriggerEvent(e);
        }


        #endregion


        #region Helpers

        private void FireTriggerEvent(VerticalSwipeProcessor.SwipeEventArgs args)
        {
            float oldValue                  = this.Value;

            if (args.Direction == VerticalSwipeProcessor.SwipeEventArgs.SwipeDirections.Negative)
            {
                LeverState currentState     = this.valueConverter.Convert(this.Value);
                if (currentState == LeverState.State0)
                {
                    this.Value              = this.valueConverter.ConvertBack(LeverState.State1);
                }
                else if (currentState == LeverState.State1)
                {
                    this.Value              = this.valueConverter.ConvertBack(LeverState.State2);
                }
            }
            else
            {
                LeverState currentState     = this.valueConverter.Convert(this.Value);
                if (currentState == LeverState.State2)
                {
                    this.Value              = this.valueConverter.ConvertBack(LeverState.State1);
                }
                else if (currentState == LeverState.State1)
                {
                    this.Value              = this.valueConverter.ConvertBack(LeverState.State0);
                }
            }

            if (oldValue != this.Value)
            { 
                this.TriggerEvent(this, new TriggerValueEventArgs(this.DataProperty, oldValue, this.Value));
            }
        }

        #endregion
    }
}
